#region Copyright (c) 2003-2004 ComponentGo!
/*
*********************************************************************
*                                                                   *
*       ComponentGo! Component Library                              *
*                                                                   *
*       Copyright (c) 2003-2004 ComponentGo!                        *
*       ALL RIGHTS RESERVED                                         *
*                                                                   *
*********************************************************************
*/
#endregion

using System;
using System.Drawing;

namespace ComponentGo.Calendars
{
	/// <summary>
	/// Provides data for the <see cref="RootCalendar.GetDayInfo"/> event.
	/// </summary>
	[System.Runtime.InteropServices.ComVisible(true)]
	public class GetDayInfoEventArgs : EventArgs {

		readonly DateTime date;
		readonly BaseCalendar cal;
		bool freeDay = false;

		/// <summary>
 		/// Constructs and sets basic fields of an object.
 		/// </summary>
 		/// <param name="cal">The calendar parameters are queried for.</param>
 		/// <param name="date">A queried date in a calendar.</param>
		public GetDayInfoEventArgs(BaseCalendar cal, DateTime date) 
		{
			mBreaks = new BreakCollection();
			this.date = date;
			this.cal = cal;

			this.workHourColor = cal.WorkHourColor;
			this.workHourColorSecond = cal.WorkHourColorSecond;
			this.freeHourColor = cal.FreeHourColor;
			this.extraBreakHourColor = cal.ExtraBreakHourColor;
			this.workHourBegin = cal.WorkHourBegin;
			this.workHourEnd = cal.WorkHourEnd;
			this.Breaks = new BreakCollection(); 
//			for(int i=0;i<cal.Breaks.Size();i++)
//			{
//				if(date.Date == cal.Breaks.GetByIndex(i).Date)
//					this.Breaks.Add(cal.Breaks.GetByIndex(i));
//			}
			
			
			DayOfWeek dow = date.DayOfWeek;
			switch (cal.FreeDay) 
			{
				case FreeDays.Sunday: 
					this.freeDay = dow==DayOfWeek.Sunday; 
					break;
				case FreeDays.Weekend: 
					this.freeDay = dow==DayOfWeek.Saturday || dow==DayOfWeek.Sunday; 
					break;
			}
		}

		/// <summary>
 		/// Supplies a date, an event was called for.
 		/// </summary>
 		/// <remarks>
 		/// Additional parameters should be set for a date supplied.
 		/// </remarks>
		public DateTime Date {
			get { return date; }
		}

		/// <summary>
		/// Information whether a given day is a holiday.
		/// </summary>
		public bool FreeDay {
			get { return freeDay; }
			set { freeDay = value; }
		}

		#region Work hours

		TimeSpan workHourBegin;
		TimeSpan workHourEnd;

		private BreakCollection mBreaks;
		/// <summary>
		/// Calendar breaks.
		/// </summary>
		public BreakCollection Breaks
		{
			set
			{
				mBreaks = value;
			}
			get
			{
				return mBreaks;
			}
		}

		/// <summary>
		/// The first working hour within a day.
		/// </summary>
		/// <remarks>
		/// Working hours are displayed in a calendar with a  <see cref="WorkHourColor"/> color.
		/// <seealso cref="WorkHourEnd"/>
		/// <seealso cref="FreeDay"/>
		/// </remarks>
		/// <example>
		/// The example shows how to set working hours from 6:00 to 14:00.
		/// <code>
		/// args.WorkHourBegin = new TimeSpan(6, 0, 0);
		/// args.WorkHourEnd = new TimeSpan(14, 0, 0);
		/// </code>
		/// </example>
		public TimeSpan WorkHourBegin 
		{
			get { return workHourBegin; }
			set { workHourBegin = cal.round(value, false); }
		}

		/// <summary>
		/// The last working hour within a day.
		/// </summary>
		/// <remarks>
		/// Working hours are displayed in a calendar with a  <see cref="WorkHourColor"/> color.
		/// <seealso cref="WorkHourBegin"/>
		/// <seealso cref="FreeDay"/>
		/// </remarks>
		/// <example>
		/// The example shows how to set working hours from 6:00 to 14:00.
		/// <code>
		/// args.WorkHourBegin = new TimeSpan(6, 0, 0);
		/// args.WorkHourEnd = new TimeSpan(14, 0, 0);
		/// </code>
		/// </example>
		public TimeSpan WorkHourEnd {
			get { return workHourEnd; }
			set { workHourEnd = cal.round(value, false); }
		}

		#endregion

		#region ResourceInfo

		internal ResourceInfo [] resourcesInfo = null;

		/// <summary>
 		/// Supplies a <see cref="GetDayInfoEventArgs.ResourceInfo"/> object containing
 		/// detailed data on a way given resource is displayed in a calendar.
 		/// </summary>
 		/// <remarks>
 		/// Allows to control individual settings of a calendar,
 		/// independently for each resource.
 		/// </remarks>
 		/// <param name="resourceIdx">Index of the resource, an object should be supplied for.</param>
 		/// <returns>A <see cref="GetDayInfoEventArgs.ResourceInfo"/> object containing
 		/// detailed data on a way given resource is displayed in a calendar.</returns>
		public ResourceInfo GetResourceInfo(int resourceIdx) 
		{
			if (!cal.isValidResource(resourceIdx, false))
				throw new IndexOutOfRangeException();

			if (resourcesInfo==null)
			{
				resourcesInfo = new ResourceInfo[cal.Resources.Count];				
			}

			if (resourcesInfo[resourceIdx]==null)
			{
				resourcesInfo[resourceIdx] = new ResourceInfo(this);
				resourcesInfo[resourceIdx].Breaks = new BreakCollection(); 
			}

			return resourcesInfo[resourceIdx];
		}

		/// <summary>
		/// A class containing detailed data on a way given resource is displayed in a calendar.
		/// </summary>
		public class ResourceInfo 
		{
			TimeSpan workHourBegin;
			TimeSpan workHourEnd;
			Color workHourColor;
			Color freeHourColor;
			Color extraBreakHourColor;
			readonly BaseCalendar cal;
			private BreakCollection mBreaks;
			/// <summary>
			/// Day breaks.
			/// </summary>
			public BreakCollection Breaks
			{
				set
				{
					mBreaks = value;
				}
				get
				{
					return mBreaks;
				}
			}

			/// <summary>
 			/// Constructs this object.
 			/// </summary>
 			/// <param name="args">Parameters of an event.</param>
			public ResourceInfo(GetDayInfoEventArgs args) {
				this.cal = args.cal;
				this.workHourBegin = args.WorkHourBegin;
				this.workHourEnd = args.WorkHourEnd;
				this.workHourColor = args.WorkHourColor;
				this.freeHourColor = args.FreeHourColor;
				this.extraBreakHourColor = args.ExtraBreakHourColor;
				this.Breaks = args.Breaks; 
			}

			/// <summary>
			/// The first working hour within a day.
			/// </summary>
			/// <remarks>
			/// Working hours are displayed in a calendar with a  <see cref="WorkHourColor"/> color.
			/// <seealso cref="WorkHourEnd"/>
			/// </remarks>
			/// <example>
			/// The example shows how to set working hours from 6:00 to 14:00.
			/// <code>
			/// ResourcesInfo[1].WorkHourBegin = new TimeSpan(6, 0, 0);
			/// ResourcesInfo[1].WorkHourEnd = new TimeSpan(14, 0, 0);
			/// </code>
			/// </example>
			public TimeSpan WorkHourBegin {
				get { return workHourBegin; }
				set { workHourBegin = cal.round(value, false); }
			}

			/// <summary>
			/// The last working hour within a day.
			/// </summary>
			/// <remarks>
			/// Working hours are displayed in a calendar with a  <see cref="WorkHourColor"/> color.
			/// <seealso cref="WorkHourBegin"/>
			/// <seealso cref="FreeDay"/>
			/// </remarks>
			/// <example>
			/// The example shows how to set working hours from 6:00 to 14:00.
			/// <code>
			/// ResourcesInfo[1].WorkHourBegin = new TimeSpan(6, 0, 0);
			/// ResourcesInfo[1].WorkHourEnd = new TimeSpan(14, 0, 0);
			/// </code>
			/// </example>
			public TimeSpan WorkHourEnd {
				get { return workHourEnd; }
				set { workHourEnd = cal.round(value, false); }
			}

			/// <summary>
			/// Background color for workdays (Monday to Friday, 8:00...16:00).
			/// </summary>
			/// <remarks>
			/// Working hours are set with <see cref="WorkHourBegin"/>  
			/// and  <see cref="WorkHourEnd"/> properties. 
			/// </remarks>
			public Color WorkHourColor {
				get { return workHourColor; }
				set { workHourColor = value; }
			}

			/// <summary>
			/// Background color for free hours, outside workdays.
			/// </summary>
			/// <remarks>
			/// Working hours are set with <see cref="WorkHourBegin"/>  
			/// and  <see cref="WorkHourEnd"/> properties. 
			/// </remarks>
			public Color FreeHourColor {
				get { return freeHourColor; }
				set { freeHourColor = value; }
			}
			public Color ExtraBreakHourColor 
			{
				get { return extraBreakHourColor; }
				set { extraBreakHourColor = value; }
			}
		}	

		#endregion

		#region Colors

		Color workHourColor;
		Color workHourColorSecond;
		Color freeHourColor;
		Color extraBreakHourColor;
		internal bool IndividualWorkColor = false;

		/// <summary>
		/// Background color for workdays (Monday to Friday, 8:00...16:00).
		/// </summary>
		/// <remarks>
		/// Working hours are set with <see cref="WorkHourBegin"/>  
		/// and  <see cref="WorkHourEnd"/> properties. 
		/// Workdays are set with a <see cref="FreeDays"/> property.
		/// </remarks>
		public Color WorkHourColor {
			get { return workHourColor; }
			set {
				if (CalendarTools.Dark(workHourColor)==workHourColorSecond)
					workHourColorSecond = CalendarTools.Dark(value);
				workHourColor = value;
				IndividualWorkColor = true;
			}
		}

		/// <summary>
		/// Second color for a <see cref="WorkHourColor"/> property used 
		/// for a linear gradient
		/// </summary>
		public Color WorkHourColorSecond {
			get { return workHourColorSecond; }
			set { 
				workHourColorSecond = value; 
				IndividualWorkColor = true;
			}
		}


		/// <summary>
		/// Background color for free hours, outside workdays.
		/// </summary>
		/// <remarks>
		/// Working hours are set with <see cref="WorkHourBegin"/>  
		/// and  <see cref="WorkHourEnd"/> properties. 
		/// Workdays are set with a <see cref="FreeDays"/> property.
		/// </remarks>
		public Color FreeHourColor {
			get { return freeHourColor; }
			set { freeHourColor = value; }
		}

		public Color ExtraBreakHourColor 
		{
			get { return extraBreakHourColor; }
			set { extraBreakHourColor = value; }
		}

		#endregion
	}

	/// <summary>
	/// Delegate invoked, when a calendar checks, whether a day is a holiday.
	/// </summary>
	/// <seealso cref="GetDayInfoEventArgs"/>
	/// <param name="sender">The source of the event.</param>
	/// <param name="args">A <see cref="GetDayInfoEventArgs"/> that contains the event data.</param>
	[System.Runtime.InteropServices.ComVisible(true)]
	public delegate void GetDayInfoEventHandler(object sender, GetDayInfoEventArgs args);

}
